﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit.RevitExtension;
using YJKArchUtils.Utils;
using YJKElementFinish.ColumnSurface.Managers;
using YJKElementFinish.WallInsulationLayer.Forms;
using YRevitJig;

namespace YJKElementFinish.WallInsulationLayer.Controllers
{
	public class PositioningCurveController
	{
		public PositioningCurveController(ExternalCommandData commandData, List<PositioningCurveController.CurveSegmentInfo> refCurveSegmentList)
		{
			this.m_Revit = commandData;
			this.m_Doc = this.m_Revit.Application.ActiveUIDocument.Document;
			this.m_lstRefCurveSegment = refCurveSegmentList;
			this.m_uiDoc = this.m_Revit.Application.ActiveUIDocument;
			this.m_drawJigCurve = new DrawJigCurve(commandData);
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public Result EditRefCurve(ref List<PositioningCurveController.CurveSegmentInfo> lstCurveSegmentInfos, ref string message)
		{
			EditCurveForm editCurveForm = new EditCurveForm();
			editCurveForm.Show(AddSurfaceLayersController._hWndRevit);
			int wMsg = 7;
			PositioningCurveController.SendMessage(AddSurfaceLayersController._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			Result result = Autodesk.Revit.UI.Result.Cancelled;
			try
			{
				for (;;)
				{
					switch (editCurveForm.CurrentOperateType)
					{
					case EditCurveForm.OperateType.OT_DrawLine:
						result = this.DrawJigLineRefCurve(editCurveForm.IsContinuous);
						break;
					case EditCurveForm.OperateType.OT_DrawRect:
						result = this.DrawJigRectRefCurve();
						break;
					case EditCurveForm.OperateType.OT_DrawArc3Pt:
						result = this.DrawJigArc3PtRefCurve(editCurveForm.IsContinuous);
						break;
					case EditCurveForm.OperateType.OT_DrawArcCenter:
						result = this.DrawJigArcCenterRefCurve();
						break;
					case EditCurveForm.OperateType.OT_SelectRefCurve:
						result = this.SelectRefCurveRefCurve();
						break;
					case EditCurveForm.OperateType.OT_SelectRefWall:
						result = this.SelectRefCurveByWall();
						break;
					case EditCurveForm.OperateType.OT_Reverse:
						result = this.Reverse();
						break;
					case EditCurveForm.OperateType.OT_Delete:
						result = this.DeleteRefCurve();
						break;
					}
					if (result == Autodesk.Revit.UI.Result.Cancelled)
					{
						if (!editCurveForm.PickButton)
						{
							break;
						}
						editCurveForm.PickButton = false;
					}
					else if (result == Autodesk.Revit.UI.Result.Failed)
					{
						break;
					}
				}
				this.ClearTagCurves();
				lstCurveSegmentInfos = this.m_lstRefCurveSegment;
				if (DialogResult.OK == editCurveForm.DialogResult)
				{
					PositioningCurveController.CreateWall = true;
				}
				else
				{
					PositioningCurveController.CreateWall = false;
				}
			}
			catch (Exception ex)
			{
				this.ClearTagCurves();
				editCurveForm.Close();
				message = ex.Message;
				return Autodesk.Revit.UI.Result.Failed;
			}
			editCurveForm.Close();
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public Result EditRefCurveNew(ref List<PositioningCurveController.CurveSegmentInfo> lstCurveSegmentInfos, ref string message)
		{
			EditingInterfaceForm editingInterfaceForm = new EditingInterfaceForm();
			editingInterfaceForm.Show(AddSurfaceLayersController._hWndRevit);
			int wMsg = 7;
			PositioningCurveController.SendMessage(AddSurfaceLayersController._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			Result result = Autodesk.Revit.UI.Result.Cancelled;
			try
			{
				for (;;)
				{
					switch (editingInterfaceForm.CurrentOperateType)
					{
					case EditingInterfaceForm.OperateType.OT_DrawLine:
						result = this.DrawJigLineRefCurve(editingInterfaceForm.IsContinuous);
						break;
					case EditingInterfaceForm.OperateType.OT_DrawRect:
						result = this.DrawJigRectRefCurve();
						break;
					case EditingInterfaceForm.OperateType.OT_DrawArc3Pt:
						result = this.DrawJigArc3PtRefCurve(editingInterfaceForm.IsContinuous);
						break;
					case EditingInterfaceForm.OperateType.OT_DrawArcCenter:
						result = this.DrawJigArcCenterRefCurve();
						break;
					case EditingInterfaceForm.OperateType.OT_SelectRefCurve:
						result = this.SelectRefCurveRefCurve();
						break;
					case EditingInterfaceForm.OperateType.OT_SelectRefWall:
						result = this.SelectRefCurveByWall();
						break;
					case EditingInterfaceForm.OperateType.OT_Reverse:
						result = this.Reverse();
						break;
					case EditingInterfaceForm.OperateType.OT_Delete:
						result = this.DeleteRefCurve();
						break;
					}
					if (result == Autodesk.Revit.UI.Result.Cancelled)
					{
						if (!editingInterfaceForm.PickButton)
						{
							break;
						}
						editingInterfaceForm.PickButton = false;
					}
					else if (result == Autodesk.Revit.UI.Result.Failed)
					{
						break;
					}
				}
				this.ClearTagCurves();
				lstCurveSegmentInfos = this.m_lstRefCurveSegment;
			}
			catch (Exception ex)
			{
				this.ClearTagCurves();
				editingInterfaceForm.Close();
				message = ex.Message;
				return Autodesk.Revit.UI.Result.Failed;
			}
			if (editingInterfaceForm.Text != "")
			{
				editingInterfaceForm.m_bIsSendEsc = false;
			}
			editingInterfaceForm.Close();
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public void DrawLines(List<Curve> lines, ref List<PositioningCurveController.CurveSegmentInfo> refCurveSegmentList)
		{
			this.DrawLines(lines);
			refCurveSegmentList = this.m_lstRefCurveSegment;
		}

		private string GetstatusPromptWithLine(int index)
		{
			string result = "选择直线墙面定位线的起始点";
			if (index % 2 == 1)
			{
				result = "选择直线墙面定位线的终点";
			}
			return result;
		}

		private Result DrawJigLineRefCurve(bool bIsContinuous)
		{
			try
			{
				for (;;)
				{
					List<Curve> lines = new List<Curve>();
					if (!bIsContinuous)
					{
						this.m_PickLastPoint = null;
					}
					if (this.m_drawJigCurve.DrawJigCurveLine(ref lines, ref this.m_PickLastPoint, this.GetstatusPromptWithLine(0), this.GetstatusPromptWithLine(1)) != null)
					{
						break;
					}
					if (!bIsContinuous)
					{
						this.m_PickLastPoint = null;
					}
					this.DrawLines(lines);
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private bool IsContinuous(bool isContinuous)
		{
			return isContinuous && this.m_PickLastPoint != null;
		}

		private string GetstatusPromptWithBox(int index)
		{
			string result = "选择墙面定位线矩形的起始点";
			if (index % 2 == 1)
			{
				result = "选择墙面定位线矩形的终点";
			}
			return result;
		}

		private Result DrawJigRectRefCurve()
		{
			this.m_PickLastPoint = null;
			try
			{
				for (;;)
				{
					List<Curve> lines = new List<Curve>();
					if (this.m_drawJigCurve.DrawJigCurveRect(ref lines, this.GetstatusPromptWithBox(0), this.GetstatusPromptWithBox(1)) != null)
					{
						break;
					}
					this.DrawLines(lines);
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private string GetstatusPromptWithArc3Pt(int index)
		{
			string result = "选择弧形墙面定位线的起始点";
			if (index % 3 == 1)
			{
				result = "选择弧形墙面定位线的终点";
			}
			else if (index % 3 == 2)
			{
				result = "选择弧形墙面定位线的线上点";
			}
			return result;
		}

		private Result DrawJigArc3PtRefCurve(bool bIsContinuous)
		{
			try
			{
				for (;;)
				{
					List<Curve> lines = new List<Curve>();
					if (!bIsContinuous)
					{
						this.m_PickLastPoint = null;
					}
					if (this.m_drawJigCurve.DrawJigCurveArc3Pt(ref lines, ref this.m_PickLastPoint, this.GetstatusPromptWithArc3Pt(0), this.GetstatusPromptWithArc3Pt(1), this.GetstatusPromptWithArc3Pt(2)) != null)
					{
						break;
					}
					if (!bIsContinuous)
					{
						this.m_PickLastPoint = null;
					}
					this.DrawLines(lines);
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private string GetstatusPromptWithArcCenter(int index)
		{
			string result = "选择弧形墙面定位线的圆心";
			if (index % 3 == 1)
			{
				result = "选择弧形墙面定位线的起始点";
			}
			else if (index % 3 == 2)
			{
				result = "选择弧形墙面定位线的终点";
			}
			return result;
		}

		private Result DrawJigArcCenterRefCurve()
		{
			this.m_PickLastPoint = null;
			try
			{
				for (;;)
				{
					List<Curve> lines = new List<Curve>();
					if (this.m_drawJigCurve.DrawJigCurveArcCenter2Pt(ref lines, this.GetstatusPromptWithArcCenter(0), this.GetstatusPromptWithArcCenter(1), this.GetstatusPromptWithArcCenter(2)) != null)
					{
						break;
					}
					this.DrawLines(lines);
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private Result SelectRefCurveRefCurve()
		{
			this.m_PickLastPoint = null;
			Transform identity = Transform.Identity;
			identity.Origin = this.m_Doc.ActiveView.Origin;
			identity.BasisX = this.m_Doc.ActiveView.RightDirection;
			identity.BasisY = this.m_Doc.ActiveView.UpDirection;
			identity.BasisZ = this.m_Doc.ActiveView.ViewDirection;
			Transform inverse = identity.Inverse;
			try
			{
				Curve curve = null;
				while (this.PickRefCurve(ref curve))
				{
					if (!this.m_bIsCyclic)
					{
						XYZ xyz = curve.GetEndPoint(0);
						xyz = inverse.OfPoint(xyz);
						xyz = identity.OfPoint(new XYZ(xyz.X, xyz.Y, 0.0));
						XYZ xyz2 = curve.GetEndPoint(1);
						xyz2 = inverse.OfPoint(xyz2);
						xyz2 = identity.OfPoint(new XYZ(xyz2.X, xyz2.Y, 0.0));
						if (!Geometry.IsEqual(xyz.DistanceTo(xyz2), 0.0))
						{
							if (curve.GetType() == typeof(Line))
							{
								this.DrawLines(new List<Curve>
								{
									Line.CreateBound(xyz, xyz2)
								});
							}
							else if (curve.GetType() == typeof(Arc))
							{
								Arc arc = curve as Arc;
								List<Curve> lines = new List<Curve>();
								this.TrasformArc(arc, xyz, xyz2, inverse, ref lines);
								this.DrawLines(lines);
							}
						}
					}
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private void TrasformArc(Arc arc, XYZ ptStart, XYZ ptEnd, Transform transform, ref List<Curve> curves)
		{
			XYZ xyz = arc.Center;
			xyz = transform.OfPoint(xyz);
			xyz = transform.OfPoint(new XYZ(xyz.X, xyz.Y, 0.0));
			if (!Geometry.IsEqual(arc.Normal, this.m_Doc.ActiveView.ViewDirection))
			{
				XYZ xyz2 = ptStart;
				ptStart = ptEnd;
				ptEnd = xyz2;
			}
			double radius = arc.Radius;
			double angle = Geometry.getAngle(xyz, ptStart, this.m_Doc.ActiveView.RightDirection, this.m_Doc.ActiveView.ViewDirection);
			double angle2 = Geometry.getAngle(xyz, ptEnd, this.m_Doc.ActiveView.RightDirection, this.m_Doc.ActiveView.ViewDirection);
			double num = Geometry.BetweenTheAngles(angle, angle2, true);
			XYZ xyz3 = Geometry.RotateTo(ptStart - xyz, num / 2.0, this.m_Doc.ActiveView.ViewDirection);
			XYZ xyz4 = xyz + xyz3;
			curves.Add(Arc.Create(ptStart, ptEnd, xyz4));
		}

		private Result SelectRefCurveByWall()
		{
			this.m_PickLastPoint = null;
			Transform identity = Transform.Identity;
			identity.Origin = this.m_Doc.ActiveView.Origin;
			identity.BasisX = this.m_Doc.ActiveView.RightDirection;
			identity.BasisY = this.m_Doc.ActiveView.UpDirection;
			identity.BasisZ = this.m_Doc.ActiveView.ViewDirection;
			Transform inverse = identity.Inverse;
			try
			{
				Curve curve = null;
				while (this.PickWallEdge(ref curve))
				{
					XYZ xyz = curve.GetEndPoint(0);
					xyz = inverse.OfPoint(xyz);
					xyz = identity.OfPoint(new XYZ(xyz.X, xyz.Y, 0.0));
					XYZ xyz2 = curve.GetEndPoint(1);
					xyz2 = inverse.OfPoint(xyz2);
					xyz2 = identity.OfPoint(new XYZ(xyz2.X, xyz2.Y, 0.0));
					if (!Geometry.IsEqual(xyz.DistanceTo(xyz2), 0.0))
					{
						if (curve.GetType() == typeof(Line))
						{
							this.DrawLines(new List<Curve>
							{
								Line.CreateBound(xyz, xyz2)
							});
						}
						else if (curve.GetType() == typeof(Arc))
						{
							Arc arc = curve as Arc;
							List<Curve> lines = new List<Curve>();
							this.TrasformArc(arc, xyz, xyz2, inverse, ref lines);
							this.DrawLines(lines);
						}
					}
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private Result SelectRefCurveByColumn()
		{
			this.m_PickLastPoint = null;
			Transform identity = Transform.Identity;
			identity.Origin = this.m_Doc.ActiveView.Origin;
			identity.BasisX = this.m_Doc.ActiveView.RightDirection;
			identity.BasisY = this.m_Doc.ActiveView.UpDirection;
			identity.BasisZ = this.m_Doc.ActiveView.ViewDirection;
			Transform inverse = identity.Inverse;
			try
			{
				Curve curve = null;
				while (this.PickColumnsEdge(ref curve))
				{
					XYZ xyz = curve.GetEndPoint(0);
					xyz = inverse.OfPoint(xyz);
					xyz = identity.OfPoint(new XYZ(xyz.X, xyz.Y, 0.0));
					XYZ xyz2 = curve.GetEndPoint(1);
					xyz2 = inverse.OfPoint(xyz2);
					xyz2 = identity.OfPoint(new XYZ(xyz2.X, xyz2.Y, 0.0));
					if (!Geometry.IsEqual(xyz.DistanceTo(xyz2), 0.0))
					{
						if (curve.GetType() == typeof(Line))
						{
							this.DrawLines(new List<Curve>
							{
								Line.CreateBound(xyz, xyz2)
							});
						}
						else if (curve.GetType() == typeof(Arc))
						{
							Arc arc = curve as Arc;
							List<Curve> lines = new List<Curve>();
							this.TrasformArc(arc, xyz, xyz2, inverse, ref lines);
							this.DrawLines(lines);
						}
					}
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private Result Reverse()
		{
			this.m_PickLastPoint = null;
			try
			{
				List<Element> list = new List<Element>();
				while (this.PickRefCurve(ref list))
				{
					List<Curve> list2 = new List<Curve>();
					List<ElementId> list3 = new List<ElementId>();
					using (List<Element>.Enumerator enumerator = list.GetEnumerator())
					{
						while (enumerator.MoveNext())
						{
							Element baseCurve = enumerator.Current;
							try
							{
								int num = this.m_lstRefCurveSegment.FindIndex((PositioningCurveController.CurveSegmentInfo item) => item.CurveId.IntegerValue == baseCurve.Id.IntegerValue);
								if (num != -1)
								{
									list3.Add(this.m_lstRefCurveSegment[num].CurveId);
									list3.AddRange(this.m_lstRefCurveSegment[num].ArrowLineIds);
									this.m_lstRefCurveSegment.RemoveAt(num);
								}
								else
								{
									list3.Add(baseCurve.Id);
								}
								Curve geometryCurve = (baseCurve as DetailCurve).GeometryCurve;
								if (geometryCurve.GetType() == typeof(Arc))
								{
									XYZ xyz = Geometry.CalculatMidPoint(geometryCurve as Arc);
									Arc item3 = Arc.Create(geometryCurve.GetEndPoint(1), geometryCurve.GetEndPoint(0), xyz);
									list2.Add(item3);
								}
								else
								{
									Line item2 = Line.CreateBound(geometryCurve.GetEndPoint(1), geometryCurve.GetEndPoint(0));
									list2.Add(item2);
								}
							}
							catch (Exception)
							{
							}
						}
					}
					PositioningCurveController.DeleteElements(this.m_Doc, list3);
					this.DrawLines(list2);
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private void ClearTagCurves()
		{
			if (this.m_TagCurves.Count == 0)
			{
				return;
			}
			PositioningCurveController.DeleteElements(this.m_Doc, this.m_TagCurves);
			this.m_TagCurves.Clear();
		}

		private Result DeleteRefCurve()
		{
			this.m_PickLastPoint = null;
			try
			{
				List<Element> list = new List<Element>();
				while (this.PickRefCurve(ref list))
				{
					List<ElementId> list2 = new List<ElementId>();
					using (List<Element>.Enumerator enumerator = list.GetEnumerator())
					{
						while (enumerator.MoveNext())
						{
							Element refCurve = enumerator.Current;
							try
							{
								int num = this.m_lstRefCurveSegment.FindIndex((PositioningCurveController.CurveSegmentInfo item) => item.CurveId.IntegerValue == refCurve.Id.IntegerValue);
								if (num != -1)
								{
									list2.Add(this.m_lstRefCurveSegment[num].CurveId);
									list2.AddRange(this.m_lstRefCurveSegment[num].ArrowLineIds);
									this.m_lstRefCurveSegment.RemoveAt(num);
								}
								else
								{
									list2.Add(refCurve.Id);
								}
							}
							catch (Exception)
							{
							}
						}
					}
					PositioningCurveController.DeleteElements(this.m_Doc, list2);
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private bool PickRefCurve(ref Curve refCurveCurve)
		{
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				DetailCurveFilter detailCurveFilter = new DetailCurveFilter();
				Reference reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, detailCurveFilter, "拾取线生成墙面定位线");
				Curve geometryCurve = (this.m_Doc.GetElement(reference) as DetailCurve).GeometryCurve;
				if (geometryCurve.IsCyclic)
				{
					YJKMessageBox.Show("圆形线不能生成定位线");
					this.m_bIsCyclic = true;
					return true;
				}
				XYZ endPoint = geometryCurve.GetEndPoint(0);
				Transform transform = Transform.CreateTranslation(new XYZ(0.0, 0.0, -endPoint.Z));
				refCurveCurve = RevitVersionFuncs.CreateTransformed(transform, geometryCurve);
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		private bool PickRefCurve(ref List<Element> refCurveList)
		{
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			RevitVersionFuncs.ClearSelection(selection);
			try
			{
				RefCurveFilter refCurveFilter = new RefCurveFilter(false);
				foreach (Element element in selection.PickElementsByRectangle(refCurveFilter, "选择墙面定位线"))
				{
					DetailCurve item = element as DetailCurve;
					refCurveList.Add(item);
				}
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		private bool PickPoint(string statusPrompt, ref XYZ ptPick)
		{
			try
			{
				ptPick = this.m_Revit.Application.ActiveUIDocument.Selection.PickPoint(statusPrompt);
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		private bool PickBox(string statusPrompt, ref XYZ ptMin, ref XYZ ptMax)
		{
			try
			{
				PickedBox pickedBox = this.m_Revit.Application.ActiveUIDocument.Selection.PickBox((Autodesk.Revit.UI.Selection.PickBoxStyle)0, statusPrompt);
				ptMin = pickedBox.Min;
				ptMax = pickedBox.Max;
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		private bool PickWallEdge(ref Curve refCurve)
		{
			Reference reference = null;
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				WallFaceFilter wallFaceFilter = new WallFaceFilter(this.m_Doc);
				reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)4, wallFaceFilter, "选择墙边界生成边线");
			}
			catch (Exception)
			{
				return false;
			}
			if (reference == null)
			{
				return false;
			}
			Face face = this.m_Doc.GetElement(reference).GetGeometryObjectFromReference(reference) as Face;
			if (null == face)
			{
				return false;
			}
			XYZ globalPoint = reference.GlobalPoint;
			double val = double.MaxValue;
			Curve curve = null;
			foreach (object obj in face.EdgeLoops)
			{
				foreach (object obj2 in ((EdgeArray)obj))
				{
					Curve curve2 = ((Edge)obj2).AsCurve();
					XYZ endPoint = curve2.GetEndPoint(0);
					XYZ endPoint2 = curve2.GetEndPoint(1);
					if (Geometry.IsEqual(endPoint.Z, endPoint2.Z))
					{
						double num = curve2.Distance(new XYZ(globalPoint.X, globalPoint.Y, endPoint.Z));
						if (Geometry.LessThan(num, val))
						{
							val = num;
							curve = curve2;
						}
					}
				}
			}
			if (curve == null)
			{
				return false;
			}
			refCurve = curve;
			return true;
		}

		public bool PickColumnsEdge(ref Curve refCurve)
		{
			bool result;
			try
			{
				Reference reference = this.m_Revit.Application.ActiveUIDocument.Selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)4, new ColumnFaceFilter(this.m_Doc), "请选择柱面：");
				Element element = this.m_Doc.GetElement(reference);
				FamilyInstance familyInstance = element as FamilyInstance;
				if (familyInstance != null)
				{
					Face face = element.GetGeometryObjectFromReference(reference) as Face;
					if (null == face)
					{
						return false;
					}
					XYZ globalPoint = reference.GlobalPoint;
					double val = double.MaxValue;
					Curve curve = null;
					foreach (object obj in face.EdgeLoops)
					{
						foreach (object obj2 in ((EdgeArray)obj))
						{
							Curve curve2 = ((Edge)obj2).AsCurve();
							if (Geometry.IsEqual(curve2.GetEndPoint(0).Z, curve2.GetEndPoint(1).Z))
							{
								double num = curve2.Distance(globalPoint);
								if (Geometry.LessThan(num, val))
								{
									val = num;
									curve = curve2;
								}
							}
						}
					}
					if (curve == null)
					{
						return false;
					}
					Transform transform = familyInstance.GetTransform();
					Curve curve3 = curve.CreateTransformed(transform);
					XYZ xyz = this.To2d((familyInstance.Location as LocationPoint).Point);
					XYZ xyz2 = this.To2d(curve.GetEndPoint(0));
					XYZ xyz3 = this.To2d(curve3.GetEndPoint(0));
					if (Geometry.LessThan(xyz.DistanceTo(xyz2), xyz.DistanceTo(xyz3)))
					{
						refCurve = curve;
					}
					else
					{
						refCurve = curve3;
					}
				}
				result = true;
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		private XYZ To2d(XYZ pt)
		{
			return new XYZ(pt.X, pt.Y, 0.0);
		}

		private void DrawStartPointTag(XYZ pos)
		{
			this.ClearTagCurves();
			CurveArray curveArray = new CurveArray();
			double num = Common.MMToFeet(300.0);
			Autodesk.Revit.DB.View activeView = this.m_Doc.ActiveView;
			XYZ startPoint = pos + -num * activeView.RightDirection + num * activeView.UpDirection;
			XYZ endPoint = pos + num * activeView.RightDirection + -num * activeView.UpDirection;
			XYZ startPoint2 = pos + -num * activeView.RightDirection + -num * activeView.UpDirection;
			XYZ endPoint2 = pos + num * activeView.RightDirection + num * activeView.UpDirection;
			Line line = YJKLineEx.YJKGetBound(startPoint, endPoint);
			curveArray.Append(line);
			Line line2 = YJKLineEx.YJKGetBound(startPoint2, endPoint2);
			curveArray.Append(line2);
			Transaction transaction = new Transaction(this.m_Doc);
			try
			{
				transaction.Start("new tag curves");
				foreach (object obj in this.m_Doc.Create.NewDetailCurveArray(this.m_Doc.ActiveView, curveArray))
				{
					DetailCurve detailCurve = (DetailCurve)obj;
					this.m_TagCurves.Add(detailCurve.Id);
				}
				transaction.Commit();
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
			}
		}

		private void DrawLines(List<EdgeInfo> lines)
		{
			List<Element> list = new List<Element>();
			this.DrawLines(lines, ref list);
		}

		private void DrawLines(List<EdgeInfo> lines, ref List<Element> linesList)
		{
			if (lines.Count == 0)
			{
				return;
			}
			CurveArray curveArray = new CurveArray();
			foreach (EdgeInfo edgeInfo in lines)
			{
				XYZ xyz = edgeInfo.StartPoint;
				if (Geometry.LessThan(xyz.Z, 0.0))
				{
					xyz = new XYZ(xyz.X, xyz.Y, 0.0);
				}
				XYZ xyz2 = edgeInfo.EndPoint;
				if (Geometry.LessThan(xyz2.Z, 0.0))
				{
					xyz2 = new XYZ(xyz2.X, xyz2.Y, 0.0);
				}
				if (!Geometry.IsEqual(xyz.DistanceTo(xyz2), 0.0))
				{
					curveArray.Append(Line.CreateBound(xyz, xyz2));
				}
			}
			this.DrawLines(curveArray, ref linesList);
		}

		private void DrawLines(List<Curve> lines)
		{
			if (lines.Count == 0)
			{
				return;
			}
			CurveArray curveArray = new CurveArray();
			foreach (Curve curve in lines)
			{
				curveArray.Append(curve);
			}
			List<Element> list = new List<Element>();
			if (this.m_bNeedTransaction)
			{
				this.DrawLines(curveArray, ref list);
				return;
			}
			this.DrawLinesWithoutTransaction(curveArray, ref list);
		}

		private void DrawLinesWithoutTransaction(CurveArray curveAry, ref List<Element> linesList)
		{
			try
			{
				DetailCurveArray detailCurveArray = this.m_Doc.Create.NewDetailCurveArray(this.m_Doc.ActiveView, curveAry);
				if (this.GetLineStyle())
				{
					foreach (object obj in detailCurveArray)
					{
						DetailCurve detailCurve = (DetailCurve)obj;
						detailCurve.LineStyle = PositioningCurveController.m_LineStyle;
						List<ElementId> arrowLineIds = new List<ElementId>();
						this.DrawArrow(detailCurve.GeometryCurve, ref arrowLineIds);
						PositioningCurveController.CurveSegmentInfo item = new PositioningCurveController.CurveSegmentInfo(detailCurve.Id, arrowLineIds);
						this.m_lstRefCurveSegment.Add(item);
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private void DrawLines(CurveArray curveAry, ref List<Element> linesList)
		{
			Transaction transaction = null;
			try
			{
				transaction = new Transaction(this.m_Doc);
				transaction.Start("draw baseline");
				DetailCurveArray detailCurveArray = this.m_Doc.Create.NewDetailCurveArray(this.m_Doc.ActiveView, curveAry);
				if (this.GetLineStyle())
				{
					foreach (object obj in detailCurveArray)
					{
						DetailCurve detailCurve = (DetailCurve)obj;
						detailCurve.LineStyle = PositioningCurveController.m_LineStyle;
						List<ElementId> arrowLineIds = new List<ElementId>();
						this.DrawArrow(detailCurve.GeometryCurve, ref arrowLineIds);
						PositioningCurveController.CurveSegmentInfo item = new PositioningCurveController.CurveSegmentInfo(detailCurve.Id, arrowLineIds);
						this.m_lstRefCurveSegment.Add(item);
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				if (transaction != null)
				{
					transaction.RollBack();
				}
			}
		}

		private void DrawArrow(Curve baseLine, ref List<ElementId> arrowIdInfo)
		{
			CurveArray curveArray = new CurveArray();
			XYZ xyz;
			XYZ xyz2;
			if (baseLine.GetType() == typeof(Arc))
			{
				Arc arc = baseLine as Arc;
				XYZ center = arc.Center;
				XYZ normal = arc.Normal;
				xyz = Geometry.CalculatMidPoint(arc);
				xyz2 = (xyz - center).Normalize();
				if (normal.IsAlmostEqualTo(-XYZ.BasisZ))
				{
					xyz2 = -xyz2;
				}
			}
			else
			{
				XYZ endPoint = baseLine.GetEndPoint(0);
				XYZ endPoint2 = baseLine.GetEndPoint(1);
				xyz = Geometry.CalculatMidPoint(endPoint, endPoint2);
				xyz2 = Geometry.RotateTo((endPoint2 - endPoint).Normalize(), -Math.PI*.5, XYZ.BasisZ);
			}
			double num = AssistFunc.mmToFeet(300.0);
			XYZ startPoint = xyz;
			XYZ xyz3 = xyz + xyz2 * num;
			XYZ xyz4 = Geometry.RotateTo(xyz2, -2.3561944901923448, XYZ.BasisZ);
			XYZ endPoint3 = xyz3 + xyz4 * (num / 2.0);
			XYZ xyz5 = Geometry.RotateTo(xyz2, 2.3561944901923448, XYZ.BasisZ);
			XYZ endPoint4 = xyz3 + xyz5 * (num / 2.0);
			Line line = YJKLineEx.YJKGetBound(startPoint, xyz3);
			curveArray.Append(line);
			Line line2 = YJKLineEx.YJKGetBound(xyz3, endPoint3);
			curveArray.Append(line2);
			Line line3 = YJKLineEx.YJKGetBound(xyz3, endPoint4);
			curveArray.Append(line3);
			try
			{
				foreach (object obj in this.m_Doc.Create.NewDetailCurveArray(this.m_Doc.ActiveView, curveArray))
				{
					DetailCurve detailCurve = (DetailCurve)obj;
					arrowIdInfo.Add(detailCurve.Id);
				}
			}
			catch (Exception ex)
			{
				string message = ex.Message;
			}
		}

		private bool GetLineStyle()
		{
			Category category = this.m_Doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines);
			if (category == null)
			{
				return false;
			}
			int num = 5;
			string text = PositioningCurveController.m_StrLineNamePrefix + num.ToString();
            Autodesk.Revit.DB.Color lineColor = new Autodesk.Revit.DB.Color(byte.MaxValue, 0, byte.MaxValue);
			if (!category.SubCategories.Contains(text))
			{
				if (!this.CreateLineStyle(num, text, lineColor, ref category))
				{
					return false;
				}
			}
			else
			{
				Category category2 = category.SubCategories.get_Item(text);
				category2.LineColor = lineColor;
				category2.SetLineWeight(num, (Autodesk.Revit.DB.GraphicsStyleType)1);
			}
			foreach (Element element in new FilteredElementCollector(this.m_Doc).OfClass(typeof(GraphicsStyle)))
			{
				GraphicsStyle graphicsStyle = element as GraphicsStyle;
				if (graphicsStyle != null && graphicsStyle.Name.CompareTo(text) == 0)
				{
					PositioningCurveController.m_LineStyle = graphicsStyle;
				}
			}
			return PositioningCurveController.m_LineStyle != null;
		}

        private bool CreateLineStyle(int lineWidth, string typeName, Autodesk.Revit.DB.Color lineColor, ref Category lineCategory)
		{
			bool result;
			try
			{
				Category category = this.m_Doc.Settings.Categories.NewSubcategory(lineCategory, typeName);
				category.LineColor = lineColor;
				category.SetLineWeight(lineWidth, (Autodesk.Revit.DB.GraphicsStyleType)1);
				result = true;
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		public static void DeleteElements(Autodesk.Revit.DB.Document doc, List<ElementId> idList)
		{
			Transaction transaction = new Transaction(doc, "clear baseline");
			transaction.Start();
			try
			{
				foreach (ElementId elementId in idList)
				{
					try
					{
						doc.Delete(elementId);
					}
					catch (Exception)
					{
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				if (transaction != null)
				{
					transaction.RollBack();
				}
			}
		}

		public static void DeleteElementsWithoutTranslation(Autodesk.Revit.DB.Document doc, List<ElementId> idList)
		{
			try
			{
				foreach (ElementId elementId in idList)
				{
					try
					{
						doc.Delete(elementId);
					}
					catch (Exception)
					{
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private ExternalCommandData m_Revit;

		private Document m_Doc;

		private static GraphicsStyle m_LineStyle = null;

		public static string m_StrLineNamePrefix = "HYWallFaceRefCurve";

		private List<PositioningCurveController.CurveSegmentInfo> m_lstRefCurveSegment = new List<PositioningCurveController.CurveSegmentInfo>();

		private List<ElementId> m_TagCurves = new List<ElementId>();

		private XYZ m_PickLastPoint;

		public bool m_bNeedTransaction = true;

		private UIDocument m_uiDoc;

		private DrawJigCurve m_drawJigCurve;

		public static bool CreateWall = false;

		private bool m_bIsCyclic;

		public class CurveSegmentInfo
		{
			public ElementId CurveId
			{
				get
				{
					return this.m_CurveId;
				}
			}

			public List<ElementId> ArrowLineIds
			{
				get
				{
					return this.m_ArrowLineIds;
				}
			}

			private CurveSegmentInfo()
			{
			}

			public CurveSegmentInfo(PositioningCurveController.CurveSegmentInfo other)
			{
				this.m_CurveId = other.CurveId;
				this.m_ArrowLineIds = other.ArrowLineIds;
			}

			public CurveSegmentInfo(ElementId curveId, List<ElementId> arrowLineIds)
			{
				this.m_CurveId = curveId;
				this.m_ArrowLineIds = arrowLineIds;
			}

			private ElementId m_CurveId = ElementId.InvalidElementId;

			private List<ElementId> m_ArrowLineIds = new List<ElementId>();
		}
	}
}
